#ifdef __cplusplus
extern "C"{
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>

#include "check_ip.h"

#define MAX_SEGMENTS 4

unsigned int ip_str_2_hex(const char *ip) {
    struct in_addr addr;
    unsigned int hex_ip;

    // 将点分十进制IP转换为网络字节序的二进制形式
    if (inet_pton(AF_INET, ip, &addr) != 1) {
        printf("Invalid IP address\n");
        return 1;
    }

    // 转换为本地字节序并输出十六进制表示
    hex_ip = ntohl(addr.s_addr);
    //printf("IP: %s -> 0x%08x\n", ip, hex_ip);
    return hex_ip;
}

static unsigned int calculate_mask_from_wildcard(const char *wildcard_ip) {
    char ip_copy[INET_ADDRSTRLEN];
    strncpy(ip_copy, wildcard_ip, sizeof(ip_copy));
    ip_copy[sizeof(ip_copy)-1] = '\0';

    // 统计固定部分（非通配符段数）
    int fixed_segments = 0;
    char *segment = strtok(ip_copy, ".");
    while (segment != NULL) {
        if (strcmp(segment, "*") == 0) break;
        fixed_segments++;
        segment = strtok(NULL, ".");
    }

    // 计算掩码位数和数值
    unsigned int mask_bits = fixed_segments * 8;
    unsigned int mask_value = (0xFFFFFFFFu << (32 - mask_bits)) & 0xFFFFFFFFu;

    return mask_value;
}

int generate_ip_from_wildcard(const char *pattern, char *ip_str, int max_ip_str) {
    int segments[MAX_SEGMENTS] = {0};       // 存储IP各段值
    int is_wildcard[MAX_SEGMENTS] = {0};    // 标记通配符位置
    int segment_count = 0;                  // 实际分段数
    int i;

    char pattern_copy[20];
    strncpy(pattern_copy, pattern, sizeof(pattern_copy) - 1);
    pattern_copy[sizeof(pattern_copy) - 1] = '\0';

    // 解析IP模式
    char *token = strtok(pattern_copy, ".");
    while (token != NULL && segment_count < MAX_SEGMENTS) {
        if (strcmp(token, "*") == 0) {
            is_wildcard[segment_count] = 1; // 标记为通配符
            segments[segment_count] = -1;   // 特殊值表示通配
        } else {
            char *endptr;
            long num = strtol(token, &endptr, 10);
            if (*endptr != '\0' || num < 0 || num > 255) {
                fprintf(stderr, "错误: 无效IP段 '%s'\n", token);
                return -1;
            }
            segments[segment_count] = (int)num;
        }
        segment_count++;
        token = strtok(NULL, ".");
    }

    if (segment_count != MAX_SEGMENTS) {
        fprintf(stderr, "错误: IP地址必须包含4个段\n");
        return -1;
    }

    for (i = 0; i < MAX_SEGMENTS; i++) {
        if (is_wildcard[i]) {
            segments[i] = 111;
        }
    }

    // 构建并验证IP地址
    snprintf(ip_str, max_ip_str, "%d.%d.%d.%d",
             segments[0], segments[1], segments[2], segments[3]);

    struct in_addr addr;
    if (inet_pton(AF_INET, ip_str, &addr) != 1) {
        fprintf(stderr, "错误: 生成的无效IP地址\n");
        return -1;
    }

    return 0;
}

int is_ip_in_network(const char * network_list[], const char* ip) {
    unsigned int hex_ip;
    char temp_ip[64]; // 包含通配符的IP是不能用于得到物理地址的，因此需要拿一个有效IP
    unsigned int mask;
    int i;
    hex_ip = ip_str_2_hex(ip);

    for(i = 0; network_list[i] != NULL ;i++) {
        if(generate_ip_from_wildcard(network_list[i], temp_ip, sizeof(temp_ip))!=0)
        {
            continue;
        }
        mask = calculate_mask_from_wildcard(network_list[i]);
        if( (hex_ip & mask) == (ip_str_2_hex(temp_ip) & mask)) {
            return i;
        }
    }
    return -1;
}
#ifdef __cplusplus
}
#endif
